home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dviselect / pkfont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-16  |  17.2 KB  |  774 lines

  1. /*
  2.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  3.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  4.  * so long as this copyright notice remains intact.
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "$Header: pkfont.c,v 1.1 88/02/11 17:08:52 jim Exp $";
  9. #endif
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include "types.h"
  15. #include "font.h"
  16. #include "num.h"
  17.  
  18. /*
  19.  * PK font operations.
  20.  *
  21.  * The spelling `nybble' is a concession to the authors of the PK format.
  22.  */
  23. int    pk_read(), pk_getgly(), pk_rasterise(), pk_freefont();
  24.  
  25. struct    fontops pkops =
  26.     { "pk", 1.0, pk_read, pk_getgly, pk_rasterise, pk_freefont };
  27.  
  28. /*
  29.  * Local info.
  30.  */
  31.  
  32. /*
  33.  * Commands.
  34.  */
  35. #define    PK_XXX1        240    /* 1 byte special */
  36. #define    PK_XXX2        241    /* 2 byte special */
  37. #define    PK_XXX3        242    /* 3 byte special */
  38. #define    PK_XXX4        243    /* 4 byte special */
  39. #define    PK_YYY        244    /* METAFONT numspecial */
  40. #define    PK_POST        245    /* marks postamble */
  41. #define    PK_NO_OP    246    /* do nothing */
  42. #define    PK_PRE        247    /* marks preamble */
  43.                 /* 248..255 undefined */
  44. #define PK_IsUndef(c)    ((c) > PK_PRE)
  45.  
  46. #define    PK_ID        89    /* marks this brand of PK file */
  47.  
  48. /*
  49.  * Information about a character packet.
  50.  */
  51. struct cp {
  52.     char    *cp_packet;    /* the beginning of the packet */
  53.     int    cp_type;    /* decoded pre type, see below */
  54. };
  55.  
  56. #define    CP_SHORT    0    /* short preamble */
  57. #define    CP_EXT_SHORT    1    /* extended short preamble */
  58. #define    CP_LONG        2    /* long preamble */
  59.  
  60. /*
  61.  * The PK details include:
  62.  *  ->    a pointer to the next byte to fetch;
  63.  *  ->    the most recent byte fetched (when we are using nextnyb());
  64.  *  ->    a flag indicating that we have used nybble 0 (bits 4..7) and
  65.  *    should use nybble 1 next;
  66.  *  ->    the base address of the memory allocated for the PK file;
  67.  *  ->    the value of dyn_f (during character translation);
  68.  *  ->    the repeat count (during rasterisation);
  69.  *  ->    the lowest glyph number that is legal;
  70.  *  ->    the highest glyph number that is legal;
  71.  *  ->    glyph instructions for the standard glyphs;
  72.  *  ->    glyph instructions for more (nonstandard) glyphs;
  73.  * and    the number of glyphs left unrasterised.
  74.  */
  75. struct pk_details {
  76.     char    *pk_ptr;    /* next byte to fetch */
  77.     int    pk_c;        /* most recent byte fetched, if nybbling */
  78.     int    pk_1nyb;    /* true => nybble 1 is next (bits 0..3) */
  79.     char    *pk_base;    /* base of allocated memory */
  80.     int    pk_dyn_f;    /* the dyn_f value */
  81.     int    pk_repeat;    /* the repeat count */
  82.     int    pk_minc;    /* minimum character value */
  83.     int    pk_maxc;    /* maximum character value */
  84. #define MAXSTD    256        /* maximum `standard' character value */
  85.     int    pk_gleft;    /* number of valid glyphs left uninterpreted */
  86.     struct    cp pk_cpack[MAXSTD];    /* for characters in [0..MAXSTD) */
  87.     struct    cp *pk_morec;        /* for characters in [MAXSTD..maxc] */
  88. };
  89.  
  90. /*
  91.  * Fetch the next byte from the PK file.
  92.  */
  93. #define    nextbyte(pk) pgetbyte((pk)->pk_ptr)
  94.  
  95. /*
  96.  * PK packed number encoding.  Nybbles in [1..dyn_f] represent themselves.
  97.  * Values in (dyn_f..13] are two-nybble values, and represent values
  98.  * dyn_f+1 through (13-dyn_f+1)*16+15.  Zero marks a long number; 14 and
  99.  * 15 specify repeat counts instead (which are another packed number).
  100.  * Note that we cannot represent the number zero as a packed number.
  101.  */
  102. #define    PK_LONGNUM    0    /* a `long number' */
  103. #define    PK_REPEAT    14    /* set repeat count */
  104. #define    PK_REPEAT1    15    /* set repeat to 1 */
  105.  
  106. /*
  107.  * Get the next nybble.  This is an expression rendition of
  108.  *    if (--pk->pk_1nyb < 0) {
  109.  *        pk->pk_1nyb = 1;
  110.  *        pk->pk_c = nextbyte(pk);
  111.  *        return (pk->pk_c >> 4);
  112.  *    } else
  113.  *        return (pk->pk_c & 0xf);
  114.  */
  115. #define    nextnyb(f) \
  116.     (--(pk)->pk_1nyb < 0 ? \
  117.      ((pk)->pk_1nyb = 1, ((pk)->pk_c = nextbyte(pk)) >> 4) : \
  118.      (pk)->pk_c & 0xf)
  119.  
  120. /*
  121.  * Get the pk_details from font f.
  122.  */
  123. #define    ftopk(f) ((struct pk_details *) (f)->f_details)
  124.  
  125. extern    int errno;
  126. char    *malloc();
  127.  
  128. /*
  129.  * PK subroutines.
  130.  */
  131.  
  132. /*
  133.  * Unpack a packed number.
  134.  */
  135. static int
  136. pk_unpack(pk)
  137.     register struct pk_details *pk;
  138. {
  139.     register int i, j;
  140.  
  141. top:
  142.     if ((i = nextnyb(pk)) == PK_LONGNUM) {
  143. #if PK_LONGNUM != 0        /* this may be silly, but . . . */
  144.         i = 0;
  145. #endif
  146.         /*
  147.          * Expand a long number.  There are one fewer leading
  148.          * zeros than there are nonzero digits to obtain, so
  149.          * count up the leading zeros, add one, and get that
  150.          * many digits.  (The `digits' are hexadecimal values.)
  151.          */
  152.         do {
  153.             i++;
  154.         } while ((j = nextnyb(pk)) == 0);
  155.         while (--i >= 0) {
  156.             j <<= 4;
  157.             j += nextnyb(pk);
  158.         }
  159.         return (j - 15 + (13 - pk->pk_dyn_f) * 16 + pk->pk_dyn_f);
  160.     }
  161.     if (i <= pk->pk_dyn_f)
  162.         return (i);
  163.     if (i < PK_REPEAT)
  164.         return ((i - pk->pk_dyn_f - 1) * 16 + nextnyb(pk) +
  165.             pk->pk_dyn_f + 1);
  166.  
  167.     /*
  168.      * There is a repeat count, either one or a packed number.
  169.      * Get it first, then start over.  (tail recursion)
  170.      */
  171.     if (i == PK_REPEAT)
  172.         pk->pk_repeat = pk_unpack(pk);
  173.     else
  174.         pk->pk_repeat = 1;
  175.     goto top;
  176. }
  177.  
  178. /*
  179.  * Skip over special commands (PK_XXX?, PK_YYY).
  180.  */
  181. static
  182. skip_specials(f)
  183.     struct font *f;
  184. {
  185.     struct pk_details *pk = ftopk(f);
  186.     register char *p = pk->pk_ptr;
  187.     register i32 i;
  188.  
  189.     for (;;) {
  190.         int tmp;
  191.         tmp = UnSign8(*p);
  192.         p++;
  193.          switch (tmp) {
  194.  
  195.         case PK_XXX1:
  196.             i = UnSign8(*p);
  197.             p++;
  198.             p += i;
  199.             break;
  200.  
  201.         case PK_XXX2:
  202.             pGetWord(p, i);
  203.             p += i;
  204.             break;
  205.  
  206.         case PK_XXX3:
  207.             pGet3Byte(p, i);
  208.             p += i;
  209.             break;
  210.  
  211.         case PK_XXX4:
  212.             pGetLong(p, i);
  213.             p += i;
  214.             break;
  215.  
  216.         case PK_YYY:
  217.             p += 4;
  218.             break;
  219.  
  220.         case PK_NO_OP:
  221.             break;
  222.  
  223.         case PK_PRE:
  224.             error(1, 0, "unexpected PK_PRE in \"%s\"", f->f_path);
  225.             break;
  226.  
  227.         default:
  228.             p--;
  229.             if (PK_IsUndef(UnSign8(*p)))
  230.                 error(1, 0, "invalid opcode %d in \"%s\"",
  231.                     f->f_path);
  232.             pk->pk_ptr = p;
  233.             return;
  234.         }
  235.     }
  236. }
  237.  
  238. /*
  239.  * Read a PK file.
  240.  */
  241. static int
  242. pk_read(f)
  243.     register struct font *f;
  244. {
  245.     register struct pk_details *pk;
  246.     register char *p;
  247.     int i, fd;
  248.     struct stat st;
  249.     char *reason;
  250.  
  251.     if ((fd = open(f->f_path, 0)) < 0)
  252.         return (-1);
  253.     pk = NULL;        /* prepare for failure */
  254.     reason = NULL;
  255.     (void) fstat(fd, &st);
  256.     if (st.st_size < 4) {    /* ??? */
  257.         reason = "file is too small";
  258.         goto fail;
  259.     }
  260.     if ((pk = (struct pk_details *) malloc(sizeof (*pk))) == NULL)
  261.         goto fail;
  262.     pk->pk_morec = NULL;
  263.     if ((pk->pk_base = malloc(st.st_size)) == NULL)
  264.         goto fail;
  265.     if (read(fd, pk->pk_base, st.st_size) != st.st_size)
  266.         goto fail;
  267.     pk->pk_ptr = pk->pk_base;
  268.     if (nextbyte(pk) != PK_PRE) {
  269.         reason = "file does not begin with PK_PRE";
  270.         goto fail;
  271.     }
  272.     if (nextbyte(pk) != PK_ID) {
  273.         reason = "bad PK_ID";
  274.         goto fail;
  275.     }
  276.     i = nextbyte(pk);
  277.     p = pk->pk_ptr + i + 4;    /* skip comment and design size */
  278.     pGetLong(p, f->f_checksum);
  279.     pk->pk_ptr = p + 4 + 4;    /* skip hppp, vppp */
  280. /* DEBUG */
  281.     f->f_details = (char *) pk;
  282.  
  283.     /* scan the characters, fail if necessary */
  284.     if (scan_characters(f, &reason))
  285.         goto fail;
  286.  
  287.     /* ignore the postamble */
  288.  
  289.     /* COMPRESS pk->pk_base DATA? */
  290.  
  291.     if (FontHasGlyphs(f, pk->pk_minc, pk->pk_maxc + 1))
  292.         goto fail;
  293.     (void) close(fd);
  294.     return (0);
  295.  
  296. fail:
  297.     if (reason) {
  298.         error(0, 0, "%s", reason);
  299.         error(0, 0, "(are you sure %s is a PK file?)", f->f_path);
  300.         errno = 0;
  301.     }
  302.     if (pk != NULL) {
  303.         if (pk->pk_base != NULL)
  304.             free(pk->pk_base);
  305.         if (pk->pk_morec != NULL)
  306.             free((char *) pk->pk_morec);
  307.         free((char *) pk);
  308.     }
  309.     (void) close(fd);
  310.     return (-1);
  311. }
  312.  
  313. /*
  314.  * Scan through the characters in the PK file, and set the offsets
  315.  * and preamble types for each of the character packets.
  316.  */
  317. static int
  318. scan_characters(f, reason)
  319.     struct font *f;
  320.     char **reason;
  321. {
  322.     register struct pk_details *pk = ftopk(f);
  323.     register i32 c, pl;
  324.       register char *p;
  325.       register struct cp *cp;
  326.       int type;
  327.  
  328. #ifdef lint
  329.     /* reason will be used someday ... I think */
  330.     reason = reason;
  331. #endif
  332.  
  333.     /* set up the minimisers and the glyph count */
  334.     pk->pk_minc = 1;
  335.     pk->pk_maxc = 0;
  336.     pk->pk_gleft = 0;
  337.  
  338.     /* mark all character packets as untouched */
  339.     for (cp = pk->pk_cpack, c = MAXSTD; --c >= 0; cp++)
  340.         cp->cp_packet = NULL;
  341.  
  342.       /*
  343.        * Loop through the packets until we reach a POST, skipping
  344.       * the glyph instructions themselves after each definition,
  345.       * and specials (if any) before each.
  346.        */
  347.      for (;; pk->pk_ptr = p + pl) {
  348.          skip_specials(f);
  349.          p = pk->pk_ptr;
  350.          if ((c = pgetbyte(p)) == PK_POST)
  351.              break;    /* whoops, done after all */
  352.  
  353.         /*
  354.          * Look at the low three bits to decide preamble size.
  355.          * A value of 7 is a `long preamble'; 4, 5, and 6 are
  356.          * `extended short preambles'; and 0, 1, 2, and 3 are
  357.          * `short preambles'.
  358.          *
  359.          * We ignore most of the preamble, reading only the
  360.          * `packet length' and the character code at this time.
  361.          */
  362.         switch (c & 7) {
  363.  
  364.         case 7:        /* long */
  365.             type = CP_LONG;
  366.             pGetLong(p, pl);
  367.             pGetLong(p, c);
  368.             break;
  369.  
  370.         case 6:
  371.         case 5:
  372.         case 4:        /* extended short */
  373.             type = CP_EXT_SHORT;
  374.             pGetWord(p, pl);
  375.             pl += (c & 3) << 16;
  376.             c = pgetbyte(p);
  377.             break;
  378.  
  379.         default:    /* short */
  380.             type = CP_SHORT;
  381.             pl = ((c & 3) << 8) + pgetbyte(p);
  382.             c = pgetbyte(p);
  383.             break;
  384.         }
  385.  
  386.         if (c >= MAXSTD) {
  387.             /*
  388.              * BEGIN XXX - should alloc pk_morec, but is hard
  389.              * and not now useful
  390.              */
  391.             error(0, 0, "ignoring character %d in \"%s\"",
  392.                 f->f_path);
  393.             error(0, 0, "because some darn programmer was lazy!");
  394.             continue;
  395.             /* END XXX */
  396.         } else
  397.             cp = &pk->pk_cpack[c];
  398.  
  399.         cp->cp_packet = pk->pk_ptr;
  400.         cp->cp_type = type;
  401.  
  402.         /* adjust range */
  403.         if (c < pk->pk_minc)
  404.             pk->pk_minc = c;
  405.         if (c > pk->pk_maxc)
  406.             pk->pk_maxc = c;
  407.  
  408.         pk->pk_gleft++;    /* and count the glyph */
  409.     }
  410.     return (0);        /* no problems */
  411. }
  412.  
  413. /*
  414.  * Obtain the specified range of glyphs.
  415.  */
  416. static int
  417. pk_getgly(f, l, h)
  418.     register struct font *f;
  419.     int l, h;
  420. {
  421.     register struct pk_details *pk = ftopk(f);
  422.     register char *p;
  423.     register struct glyph *g;
  424.     register int i;
  425.     register struct cp *cp;
  426.  
  427.     if (pk == NULL)
  428.         panic("pk_getgly(%s)", f->f_path);
  429.     for (i = l; i < h; i++) {
  430.           if (i < MAXSTD)
  431.               cp = &pk->pk_cpack[i];
  432.          else {
  433.              if (i > pk->pk_maxc)
  434.                  panic("pk_getgly(%s, %d)", f->f_path, i);
  435.               cp = &pk->pk_morec[i - MAXSTD];
  436.          }
  437.           p = cp->cp_packet;
  438.           if (p == NULL)    /* glyph is not valid */
  439.             continue;
  440.         g = f->f_gly[i];
  441.         p++;        /* skip flag */
  442.         switch (cp->cp_type) {
  443.  
  444.         case CP_LONG:
  445.             p += 8;    /* skip packet len, character code */
  446.             pGetLong(p, g->g_tfmwidth);
  447. #ifdef notyet
  448.             pGetLong(p, g->g_xescapement);
  449.             pGetLong(p, g->g_yescapement);
  450. #else
  451.             p += 8;
  452. #endif
  453.             pGetLong(p, g->g_width);
  454.             pGetLong(p, g->g_height);
  455.             pGetLong(p, g->g_xorigin);
  456.             pGetLong(p, g->g_yorigin);
  457.             break;
  458.  
  459.         case CP_EXT_SHORT:
  460.             p += 3;    /* skip packet len, character code */
  461.             pGet3Byte(p, g->g_tfmwidth);
  462. #ifdef notyet
  463.             { i32 dm; pGetWord(p, dm);
  464.             g->g_xescapement = dm << 16; }
  465.             g->g_yescapement = 0;
  466. #else
  467.             p += 2;    /* skip dm */
  468. #endif
  469.             pGetWord(p, g->g_width);
  470.             pGetWord(p, g->g_height);
  471.             pGetWord(p, g->g_xorigin);
  472.             g->g_xorigin = Sign16(g->g_xorigin);
  473.             pGetWord(p, g->g_yorigin);
  474.             g->g_yorigin = Sign16(g->g_yorigin);
  475.             break;
  476.  
  477.         case CP_SHORT:
  478.             p += 2;    /* skip packet len, character code */
  479.             pGet3Byte(p, g->g_tfmwidth);
  480. #ifdef notyet
  481.             g->g_xescapement = pgetbyte(p) << 16;
  482.             g->g_yescapement = 0;
  483. #else
  484.             p++;    /* skip dm */
  485. #endif
  486.             g->g_width = pgetbyte(p);
  487.             g->g_height = pgetbyte(p);
  488.             g->g_xorigin = pgetbyte(p);
  489.             g->g_xorigin = Sign8(g->g_xorigin);
  490.             g->g_yorigin = pgetbyte(p);
  491.             g->g_yorigin = Sign8(g->g_yorigin);
  492.             break;
  493.         }
  494.         g->g_flags = GF_VALID;
  495.         g->g_un.g_details = p;
  496.     }
  497.     return (0);
  498. }
  499.  
  500. /*
  501.  * Bit masks for pk_rasterise().
  502.  */
  503. static char bmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
  504. static char rbits[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  505.  
  506. /*
  507.  * Obtain rasters for the specified glyphs.
  508.  */
  509. static int
  510. pk_rasterise(f, l, h)
  511.     struct font *f;
  512.     int l, h;
  513. {
  514.     struct pk_details *pk0;
  515.     struct glyph *g0;
  516.     char *p0, *rp0;
  517.     int flag, ii;
  518.  
  519.     if ((pk0 = ftopk(f)) == NULL)
  520.         panic("pk_rasterise(%s)", f->f_path);
  521.     for (ii = l; ii < h; ii++) {
  522.         {
  523.             register struct glyph *g;
  524.             register char *p;
  525.             register int i;
  526.  
  527.             g = f->f_gly[i = ii];
  528.             if ((g->g_flags & GF_VALID) == 0)
  529.                 continue;    /* no glyph */
  530.             if (!HASRASTER(g))    /* empty raster */
  531.                 goto done;
  532.  
  533.             /*
  534.              * Allocate a raster.
  535.              */
  536.             rp0 = malloc(((g->g_width + 7) >> 3) * g->g_height);
  537.             if ((g->g_raster = rp0) == NULL)
  538.                 return (-1);/* ??? */
  539.             g->g_rotation = ROT_NORM;
  540.  
  541.             /*
  542.              * Pick up the flag byte, then start at the real
  543.              * packet, which we saved in g_details.
  544.              */
  545.             if (i < MAXSTD)
  546.                 p = pk0->pk_cpack[i].cp_packet;
  547.             else
  548.                 p = pk0->pk_morec[i - MAXSTD].cp_packet;
  549.             flag = UnSign8(*p);
  550.             p0 = g->g_un.g_details;
  551.             g0 = g;
  552.         }
  553.         if ((pk0->pk_dyn_f = flag >> 4) == 14) {
  554.             register char *p = p0, *rp = rp0;
  555.             register int j, ls, rs, i, w;
  556.  
  557.             /*
  558.              * Expand a bit-packed representation.
  559.              * If we get lucky, it is byte packed and
  560.              * we can just copy it over.
  561.              */
  562.             i = g0->g_height;
  563.             j = g0->g_width;
  564.             if ((j & 7) == 0) {
  565.                 bcopy(p, rp, i * (j >> 3));
  566.                 goto done;
  567.             }
  568.  
  569.             /*
  570.              * No such luck.
  571.              */
  572.             w = j;
  573.             ls = 0;
  574.             while (--i >= 0) {
  575. #if defined(vax) && !defined(lint)
  576.                 /* have to work on the compiler someday */
  577.                 rs = ls - 8;
  578. #else
  579.                 rs = 8 - ls;
  580. #endif
  581.                 /* know j always != 8 */
  582.                 for (j = w; j > 8; j -= 8) {
  583. #if defined(vax) && !defined(lint)
  584.                     asm("    movb    (r11)+,r0");
  585.                     asm("    ashl    r8,r0,r0");
  586.                     asm("    movb    r0,(r10)");
  587.                     asm("    movzbl    (r11),r0");
  588.                     asm("    ashl    r7,r0,r0");
  589.                     asm("    bisb2    r0,(r10)+");
  590. #else
  591.                     *rp = *p << ls;
  592.                     p++;
  593.                     *rp |= UnSign8(*p) >> rs;
  594.                     rp++;
  595. #endif
  596.                 }
  597.  
  598.                 /*
  599.                  * We need j more bits; there are rs
  600.                  * bits available at *p.  Ask for j,
  601.                  * which gets min(j, rs).
  602.                  */
  603. #if defined(vax) && !defined(lint)
  604.                 /*void*/; /* avoid asm() label botch */
  605.                 asm("    movb    (r11),r0");
  606.                 asm("    ashl    r8,r0,r0");
  607.                 asm("    mcomb    _bmask[r9],r1");
  608.                 asm("    bicb2    r1,r0");
  609.                 asm("    movb    r0,(r10)+");
  610. #else
  611.                 *rp++ = (*p << ls) & bmask[j];
  612. #endif
  613.                 /* account for j bits */
  614.                 ls += j; ls &= 7;
  615.                 /* then adjust j based on rs */
  616. #if defined(vax) && !defined(lint)
  617.                 j += rs;
  618. #else
  619.                 j -= rs;
  620. #endif
  621.                 /* still need j more bits */
  622.                 if (j < 0)    /* got them all */
  623.                     continue;
  624.                 p++;
  625.                 if (j == 0)    /* there were just enough */
  626.                     continue;
  627.                 /* take j more bits */
  628. #if defined(vax) && !defined(lint)
  629.                 /*void*/; /* avoid asm() label botch */
  630.                 asm("    mcomb    _bmask[r9],r0");
  631.                 asm("    bicb3    r0,(r11),r0");
  632.                 asm("    movzbl    r0,r0");
  633.                 asm("    ashl    r7,r0,r0");
  634.                 asm("    bisb2    r0,-1(r10)");
  635. #else
  636.                 rp[-1] |= UnSign8(*p & bmask[j]) >> rs;
  637. #endif
  638.             }
  639.         } else {
  640.             register struct pk_details *pk = pk0;
  641.             register int on = flag & 8 ? 0xff : 0;
  642.             register char *rowp;    /* pointer into this row */
  643.             register int j;        /* trimmed run count */
  644.             register int k;        /* misc */
  645.             register int b;        /* bit index in current col */
  646.             register int i;        /* run count */
  647.             register int colsleft;    /* columns left this row */
  648.             register int rowsleft;    /* rows left */
  649.             static char *row;    /* a one-row buffer */
  650.             static int rowsize;    /* and its size in bytes */
  651.             int wb;            /* row width in bytes */
  652.  
  653.             wb = (g0->g_width + 7) >> 3;
  654.             if (rowsize < wb) {    /* get more row space */
  655.                 if (row)
  656.                     free(row);
  657.                 /* keep a slop byte */
  658.                 row = malloc((unsigned) (wb + 1));
  659.                 if (row == NULL)
  660.                     return (-1);    /* ??? */
  661.                 rowsize = wb;
  662.             }
  663.             bzero(row, wb);
  664.             rowsleft = g0->g_height;
  665.             colsleft = g0->g_width;
  666.             pk->pk_repeat = 0;
  667.             pk->pk_ptr = p0;
  668.             pk->pk_1nyb = 0;    /* start on nybble 0 */
  669.             rowp = row;
  670.             b = 0;
  671.             while (rowsleft > 0) {    /* do all rows */
  672.                 /* EXPAND IN LINE? */
  673.                 i = pk_unpack(pk);
  674.                 /*
  675.                  * Work until the run count is exhausted
  676.                  * (or at least pretty tired).
  677.                  *
  678.                  * (Okay, so the joke is stolen!)
  679.                  */
  680.                 while ((j = i) > 0) {
  681.                     /*
  682.                      * If the count is more than the
  683.                      * rest of this row, trim it down.
  684.                      */
  685.                     if (j > colsleft)
  686.                         j = colsleft;
  687.                     i -= j;    /* call them done */
  688.                     /*
  689.                      * We need k=8-b bits to finish
  690.                      * up the current byte.  If we
  691.                      * can finish it, do so; the proper
  692.                      * bits to set are in rbits[k].
  693.                      */
  694.                     if (j >= (k = 8 - b)) {
  695.                         j -= k;
  696.                         colsleft -= k;
  697.                         *rowp++ |= on & rbits[k];
  698.                         b = 0;
  699.                     }
  700.                     /*
  701.                      * Set any full bytes.
  702.                      */
  703.                     while (j >= 8) {
  704.                         *rowp++ = on;
  705.                         j -= 8;
  706.                         colsleft -= 8;
  707.                     }
  708.                     /*
  709.                      * Finally, begin a new byte, or
  710.                      * add to the current byte, with
  711.                      * j more bits.  We know j <= 8-b.
  712.                      * (If j==0, we may be writing on
  713.                      * our slop byte, which is why we
  714.                      * keep one around....)
  715.                      */
  716. if (j > 8-b) panic("pk_rasterise j>8-b");
  717.                     *rowp |= (on & bmask[j]) >> b;
  718.                     colsleft -= j;
  719.                     b += j; b &= 7;
  720.                     if (colsleft == 0) {
  721.                         pk->pk_repeat++;
  722.                         rowsleft -= pk->pk_repeat;
  723.                         while (--pk->pk_repeat >= 0) {
  724.                             bcopy(row, rp0, wb);
  725.                             rp0 += wb;
  726.                         }
  727. if (rowsleft == 0 && i) panic("pk_rasterise leftover bits");
  728.                         pk->pk_repeat = 0;
  729.                         rowp = row;
  730.                         colsleft = g0->g_width;
  731.                         bzero(row, wb);
  732.                         b = 0;
  733.                     }
  734.                 }
  735.                 on = 0xff - on;
  736.             }
  737.         }
  738.  
  739. done:
  740.         /*
  741.          * Successfully converted another glyph.
  742.          */
  743.         pk0->pk_gleft--;
  744.     }
  745.  
  746. if (pk0->pk_gleft < 0)
  747. panic("%s: gleft==%d", f->f_path, pk0->pk_gleft);
  748.     if (pk0->pk_gleft == 0) {
  749.         free(pk0->pk_base);
  750.         if (pk0->pk_morec != NULL)
  751.             free((char *) pk0->pk_morec);
  752.         free((char *) pk0);
  753.         f->f_details = NULL;
  754.     }
  755.     return (0);
  756. }
  757.  
  758. /*
  759.  * Discard the font details.
  760.  */
  761. static
  762. pk_freefont(f)
  763.     struct font *f;
  764. {
  765.     register struct pk_details *pk = ftopk(f);
  766.  
  767.     if (pk != NULL) {
  768.         free(pk->pk_base);
  769.         if (pk->pk_morec != NULL)
  770.             free((char *) pk->pk_morec);
  771.         free((char *) pk);
  772.     }
  773. }
  774.